#ifndef listh

#define listh
#include <iostream>
struct empty_list
{
};

template<int value_, typename list_> struct list
{
   static const int head = value_;
   typedef list_ tail;
};

template<typename l_1, typename l_2> struct concat
{
   typedef 
      list<
         l_1::head, 
         typename concat<
            typename l_1::tail, 
            l_2
         >::type
      > 
      type;
};

template<typename l_2> struct concat<empty_list, l_2>
{
   typedef l_2 type;
};

template<typename l_1> struct concat<l_1, empty_list>
{
   typedef l_1 type;
};

template<int I, typename T>
std::ostream& operator<<(std::ostream& os, const list<I, T>&)
{
   return os << I << " " << T();
}

std::ostream& operator<<(std::ostream& os, empty_list);
#endif
